﻿
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

namespace View
{
    public enum ViewLayer
    {
        Normal,
        Game,
        Middle,
        Top,
        NetWork,
    }

    public enum ViewType
    {
        Hall,
        Game
    }

    public class UIManager
    {

        public static UIManager Instance = new UIManager();


        private Canvas canvas;
        public Dictionary<string, IView> viewDic = new Dictionary<string, IView>();
        private Dictionary<string, IView> multiviewHallDic = new Dictionary<string, IView>();
        private Dictionary<ViewLayer, RectTransform> layerDic = new Dictionary<ViewLayer, RectTransform>();

        public Dictionary<string, IView> viewHallDic = new Dictionary<string, IView>();
        public Dictionary<string, IView> viewGameDic = new Dictionary<string, IView>();

        public IView waitDic = null;
        public void Init(Canvas canvas)
        {
            this.canvas = canvas;
           
            layerDic[ViewLayer.Normal] = CreatViewLayer(ViewLayer.Normal);
            layerDic[ViewLayer.Game] = CreatViewLayer(ViewLayer.Game); 
            layerDic[ViewLayer.Middle] = CreatViewLayer(ViewLayer.Middle);
            layerDic[ViewLayer.Top] = CreatViewLayer(ViewLayer.Top);
            layerDic[ViewLayer.NetWork] = CreatViewLayer(ViewLayer.NetWork);
        }
        private RectTransform CreatViewLayer(ViewLayer layer)
        {
            GameObject obj = new GameObject(layer.ToString());
            RectTransform rect = obj.AddComponent<RectTransform>();
            rect.parent = canvas.transform;
            rect.anchorMin = Vector2.zero;
            rect.anchorMax = Vector2.one;
            rect.localScale = Vector3.one;
            rect.offsetMin = Vector2.zero;
            rect.offsetMax = Vector2.zero;
            rect.localPosition = Vector3.zero;
            return rect;
        }
        public IView Show(string viewName, params object[] args)
        {
            return Show(viewName, ViewLayer.Normal, args);
        }
        public IView Show(string viewName, ViewLayer rootType, params object[] args)
        {
            return Show(viewName, rootType, ViewType.Hall, args);
        }
        
        public IView Show(string viewName, ViewLayer rootType, ViewType viewType= ViewType.Hall, params object[] args)
        {
            IView view = null;
            Dictionary<string, IView> view_Panel;
            if (viewType == ViewType.Hall)
            {
                view_Panel = viewHallDic;
            }
            else
            {
                view_Panel = viewGameDic;
                
            }
            //Debug.LogError("zziiiiiiiiiiiiiii");
            if (!view_Panel.TryGetValue(viewName, out view))
            {
                view = CreatView(viewName, rootType, viewType);

                view_Panel[viewName] = view;
                view.Load();
            }
            else
            {
                //Debug.LogError("uuuuuuuuuuuuuuuuuuuuuuu");
            }
            view.Context.transform.SetAsLastSibling();
            view.Show(args);
            return view;
        }


        /// <summary>
        ///检测面板是否打开
        /// </summary>
        /// <param name="viewName"></param>
        /// <param name="viewType"></param>
        /// <returns></returns>
        public bool IsViewActiveSelf(string viewName, ViewType viewType = ViewType.Hall)
        {
            Dictionary<string, IView> view_Panel;
            if (viewType == ViewType.Hall)
            {
                view_Panel = viewHallDic;
            }
            else
            {
                view_Panel = viewGameDic;

            }
            if (view_Panel.ContainsKey(viewName))
            {
                return view_Panel[viewName].Context.activeSelf;
            }
            return false;
        }
        
        
        /// <summary>
        /// 显示tips
        /// </summary>
        /// <param name="content"></param>
        public void ShowToolTips(string content)
        {
            // Show(ViewName.ToolTipsView, ViewLayer.Top, content);
        }

        /// <summary>
        /// 进游戏
        /// </summary>
        /// <param name="viewName"></param>
        public void LoadGame(string viewName)
        {
            Show(viewName, ViewLayer.Game, ViewType.Game);
            List<string> viewnameList = new List<string>();

            foreach (var item in viewHallDic)
            {
                Close(item.Key, ViewType.Hall);
                // if (item.Key!=ViewName.HallView)
                {
                    
                    viewnameList.Add(item.Key);
                }
                
            }
            for (int i = 0; i < viewnameList.Count; i++)
            {
                GameObject.Destroy(viewHallDic[viewnameList[i]].Context);
                viewHallDic.Remove(viewnameList[i]);
            }

        }
        public void CloseAllPanel()
        {
            List<string> viewnameList = new List<string>();
            foreach (var item in viewHallDic)
            {
                Close(item.Key, ViewType.Hall);
                viewnameList.Add(item.Key);
            }
        }
        public void CloseAllGamePanel()
        {
            List<string> viewnameList = new List<string>();

            foreach (var item in viewGameDic)
            {
                Close(item.Key, ViewType.Game);
                viewnameList.Add(item.Key);
            }
            for (int i = 0; i < viewnameList.Count; i++)
            {
                GameObject.Destroy(viewGameDic[viewnameList[i]].Context);
                viewGameDic.Remove(viewnameList[i]);
            }
        }
        /// <summary>
        /// 游戏返回大厅
        /// </summary>
        /// <param name="viewName"></param>
        public void LoadGameToHall(string viewName)
        {
            Show(viewName, ViewLayer.Normal, ViewType.Hall);
            List<string> viewnameList = new List<string>();

            foreach (var item in viewGameDic)
            {
                Close(item.Key, ViewType.Game);
                viewnameList.Add(item.Key);
            }
            for (int i = 0; i < viewnameList.Count; i++)
            {
                GameObject.Destroy(viewGameDic[viewnameList[i]].Context);
                viewGameDic.Remove(viewnameList[i]);
            }
        }
        /// <summary>
        /// 创建界面-创建弹窗界面专用
        /// </summary>
        /// <param name="viewName">界面名</param>
        /// <param name="fileName">资源文件名</param>
        /// <param name="args">额外参数</param>
        /// <returns></returns>
        public async Task<IView> Show(string viewName, string fileName, params object[] args)
        {
            IView view = null;
            if (!viewHallDic.TryGetValue(viewName, out view))
            {
                view = await CreatView(viewName, fileName, ViewLayer.Middle);

                viewHallDic[viewName] = view;
                view.Load();
                //统一加上点击关闭
                Button close_btn = view.Context.transform.Find("bg_shade").GetComponent<Button>();
                if (close_btn != null)
                {
                    close_btn.onClick.RemoveAllListeners();
                    close_btn.onClick.AddListener(()=> 
                    {
                        Close(viewName);
                    });
                }
            }
            //view.Context.SetActive(true);
            view.Show(args);
            return view;
        }

        public IView ShowWait(params object[] args)
        {
            if (waitDic == null)
            {
                // waitDic = CreatView(ViewName.WaitView,ViewLayer.NetWork, ViewType.Hall);
                waitDic.Load();
            }
            waitDic.Show(args);
            return waitDic;
        }
        public void CloseWait( params object[] args)
        {
            Debug.LogError("===========CloseWait==========");
            if (waitDic != null)
            {
                waitDic.Close(args);
            }


        }


        ////提示框
        //public IView ShowTips(string msg)
        //{
        //    return ShowTips(msg, RootType.Hint);
        //}

        public void LoadIcon(Image icon, string abname, string assetname)
        {
            icon.sprite = ResourceManager.Instance.LoadSprite(abname, assetname);
            //icon.SetNativeSize();
        }

        public Texture LoadTexture(string abname, string assetname)
        {
            Texture t = ResourceManager.Instance.LoadTexture(abname, assetname);
            return t;
            //icon.SetNativeSize();
        }

        public async Task<Texture> LoadTextureAsys(string abname, string assetname)
        {
            Texture t =await ResourceManager.Instance.LoadTextureAsync(abname, assetname);
            return t;
            //icon.SetNativeSize();
        }

        //public IView ShowTips(string msg, RootType rootType)
        //{
        //    return ShowMultiView(ViewName.TipsView, rootType,msg);
        //}

        //public IView ShowWait(float time=-1)
        //{
        //    return ShowMultiView(ViewName.WaitView,RootType.Top,time);
        //}

        //二次确认框

        //public IView ShowConfirm(IConfirmParam msg,  string viewDefin)
        //{
        //    return ShowConfirm(msg, RootType.Pop, viewDefin);
        //}

        //public IView ShowConfirm(IConfirmParam msg, RootType rootType, string viewDefin)
        //{
        //    return ShowMultiDefineView(ViewName.ConfirmView, rootType, viewDefin, msg);
        //}

        private IView CreatView(string viewName, ViewLayer layer, ViewType viewType)
        {
            string className = "View.Instant." + viewName;
            string path = "Hall/Prefab/" + viewName;
            if (viewType == ViewType.Game)
            {
                path = viewName + "/Prefab";
            }
            IView view = Utils.Reflect(className) as IView;
            GameObject prefab = ResourceManager.Instance.LoadPrefab(path, viewName);
            Transform prent = layerDic[layer];

            view.Context = GameObject.Instantiate<GameObject>(prefab, prent);
            view.Name = viewName;
            return view;
        }
        /// <summary>
        /// 创建界面
        /// </summary>
        /// <param name="viewName">界面名</param>
        /// <param name="fileName">资源文件名</param>
        /// <param name="rootType">层级</param>
        /// <returns></returns>
        private async Task<IView> CreatView(string viewName, string fileName, ViewLayer layer)
        {
            Debug.Log(viewName + "    viewName");
            Debug.Log(fileName + "    fileName");
            string className = "View.Instant." + viewName;
            IView view = Utils.Reflect(className) as IView;
            GameObject prefab = await ResourceManager.Instance.LoadPrefabAsync("prefab/view/" + viewName, viewName);
            Transform prent = layerDic[layer];
            view.Context = GameObject.Instantiate<GameObject>(prefab, prent);
            view.Name = viewName;
            return view;
        }

        public void Close(string viewName, ViewType viewType = ViewType.Hall, params object[] args)
        {
            if (viewType== ViewType.Hall)
            {
                if (viewHallDic.ContainsKey(viewName))
                {
                    IView view = viewHallDic[viewName];
                    view.Close(args);
                    //if ((bool)args[0]==true)
                    //{
                    //    viewHallDic.Remove(viewName);
                    //}
                }
            }
            else if (viewType == ViewType.Game)
            {
                if (viewGameDic.ContainsKey(viewName))
                {
                    IView view = viewGameDic[viewName];
                    view.Close(args);
                    //if ((bool)args[0]==true)
                    //{
                    //    viewHallDic.Remove(viewName);
                    //}
                }
            }
            
        }

        public void CloseGame(string viewName, params object[] args)
        {
            if (viewHallDic.ContainsKey(viewName))
            {
                IView view = viewHallDic[viewName];
                view.Close(args);
            }
        }

        //多面板
        public IView ShowMultiView(string viewName, ViewLayer rootType,params object[] args)
        {
            IView view = CreatView(viewName, rootType, ViewType.Hall);
            view.Load();
            view.Show(args);
            return view;
        }

        //多面板
        public IView ShowMultiDefineView(string viewName, ViewLayer rootType, string viewDefine, params object[] args)
        {
            IView view = null;
            if (viewDefine != null)
            {
                if (multiviewHallDic.ContainsKey(viewDefine))
                {
                    view = multiviewHallDic[viewDefine];
      
                }
                else
                {
                    view = CreatView(viewName, rootType, ViewType.Hall);
                    multiviewHallDic[viewDefine] = view;
                    view.Load();
                }
            }
            else
            {
                view = CreatView(viewName, rootType, ViewType.Hall);
                view.Load();
            }
            view.Show(args);
            return view;
        }

        public void closeMultiView(string viewDefine)
        {
            if (multiviewHallDic.ContainsKey(viewDefine))
            {
                IView view = multiviewHallDic[viewDefine];
                view.Close();
                multiviewHallDic.Remove(viewDefine);
            }
        }

        public void OnShowLoading()
        {
            Show(ViewName.LoadingView, ViewLayer.Top);
        }
        public void OnCloseLoading()
        {
            Close(ViewName.LoadingView);
        }
    }
}
